package io.renren.modules.member.controller;

import com.alibaba.fastjson.JSON;
import com.qiniu.util.Json;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.utils.SnowFlake;
import io.renren.common.validator.ValidatorUtils;
import io.renren.modules.member.entity.MemberEntity;
import io.renren.modules.member.rfid.RfidTool;
import io.renren.modules.member.service.ExcelService;
import io.renren.modules.member.service.MemberService;
import io.renren.modules.member.service.impl.RfidModifyService;
import io.renren.modules.oss.service.SysOssService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * 学员
 *
 * @author Mark 军事体育训练考核系统
 */
@RestController
@RequestMapping("member/member")
public class MemberController {

    private final Logger logger = LoggerFactory.getLogger(MemberController.class);

    @Autowired
    private MemberService memberService;

    @Autowired
    private SysOssService sysOssService;

    @Autowired
    private ExcelService excelService;

    @Autowired
    private RfidModifyService rfidModifyService;

    @Autowired
    private Environment env;

    private static final String OUT_FILE_NAME = "人员基本信息";

    private static final String OUT_FILE_NAME_TEMP = "人员信息模板.xlsx";

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("member:member:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = memberService.queryPage(params);

        return R.ok().put("page", page);
    }

    /**
     * 按条件查询所有人员
     */
    @RequestMapping("/findAll")
    public R findAll(@RequestParam Map<String, Object> params) {
        return R.ok().put("data", memberService.findByCondition(params));
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("member:member:info")
    public R info(@PathVariable("id") Long id){
        MemberEntity member = memberService.getById(id);

        return R.ok().put("member", member);
    }

    /**
     * 查找EPC编码
     */
    @RequestMapping("/findEpc")
    @RequiresPermissions("member:member:info")
    public R findEpc(){
        return R.ok().put("epc", RfidTool.EPC_MAP.get(RfidTool.EPC_KEY));
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    @RequiresPermissions("member:member:save")
    public R save(@RequestBody MemberEntity member){
        //校验类型
        ValidatorUtils.validateEntity(member);
        String result = memberService.checkIcCode(member);
        if (StringUtils.isBlank(result)) {
            memberService.save(member);
            return R.ok();
        } else {
            return R.error("手环IC编码已经被编码为【"+result+"】的人占用");
        }

    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("member:member:update")
    public R update(@RequestBody MemberEntity member){
        //校验类型
        ValidatorUtils.validateEntity(member);
        String result = memberService.checkIcCode(member);
        if (StringUtils.isBlank(result)) {
            memberService.updateById(member);
            return R.ok();
        } else {
            return R.error("手环IC编码已经被编码为【"+result+"】的人占用");
        }
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @RequiresPermissions("member:member:delete")
    public R delete(@RequestBody Long[] ids){
        memberService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    @RequestMapping("/downloadExTemp")
    @RequiresPermissions("member:member:save")
    public String downloadExTemp(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        String path = this.getClass().getResource("/excel/人员信息模板.xlsx").getFile();
//        path = java.net.URLDecoder.decode(path,"utf-8");
//        File file = new File(path);
//        String path = ResourceUtils.getURL("classpath:").getPath();
//        File file = new File(path, "/excel/人员信息模板.xlsx");

        String path = java.net.URLDecoder.decode(env.getProperty("download.excel"), "utf-8");
        File file = new File(path, "excel/人员信息模板.xlsx");
        sysOssService.download(request, response, file, OUT_FILE_NAME_TEMP);
        return null;
    }

    @RequestMapping("/upload/{type}")
    @RequiresPermissions("member:member:save")
    public R upload(@RequestParam("file") MultipartFile file, @PathVariable("type") String type) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        //上传文件
        sysOssService.upload(file);
        int count = 0;
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        if (StringUtils.isNotBlank(suffix) &&
                (StringUtils.equals(suffix.toLowerCase(), ".xls") || StringUtils.equals(suffix.toLowerCase(), ".xlsx"))) {
            // 解析excel
            InputStream inputStream = file.getInputStream();
            List<List<Object>> list = excelService.getBankListByExcel(inputStream, file.getOriginalFilename());
            inputStream.close();
            // 各属性与Excel的列对应关系
            Map<String, Integer> position = getExcelPosition(type);
            count = memberService.batchSaveExcelMember(list, position);
        } else if (StringUtils.isNotBlank(suffix) && StringUtils.equals(suffix.toLowerCase(), ".txt")) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
            List<String> list = new ArrayList<>();
            String lineStr = null;
            while ((lineStr = reader.readLine()) != null) {
                logger.info("文本文件：{}", lineStr);
                list.add(lineStr);
            }
            reader.close();
            logger.info("文本文件OK");
        }

        return R.ok().put("msg", "学员信息登记成功个数： " + count);
    }

    private Map<String, Integer> getExcelPosition(String type) {
        Map<String, Integer> position = new HashMap<>();
        if (StringUtils.equals(type, "1")) {
            position.put("studentCode", 0);
            position.put("name", 1);
            position.put("sex", 2);
            position.put("birthday", 3);
            position.put("type", 4);
            position.put("icCode", 5);
        }
        return position;
    }


    @RequestMapping("/download")
    @RequiresPermissions("member:member:download")
    public String download(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("name", request.getParameter("name"));
        param.put("studentCode", request.getParameter("studentCode"));
        param.put("type", request.getParameter("type"));
        param.put("sex", request.getParameter("sex"));
        List<String> titles = new ArrayList();
        List<List<String>> excelValues =  memberService.downExcelByCondition(param, titles);
        excelService.writeExcel(request, response, OUT_FILE_NAME, titles, excelValues);
        return null;
    }

    @RequestMapping("/download/txt")
    @RequiresPermissions("member:member:download")
    public String downloadTxt(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> param = new HashMap<>();
        String txtValue = JSON.toJSONString(memberService.findByCondition(param));
        String userAgent = request.getHeader("User-Agent");
        String downLoadFileName = "人员基本信息.txt";
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            downLoadFileName = java.net.URLEncoder.encode(downLoadFileName, "UTF-8");
        } else {// 非IE浏览器的处理：
            downLoadFileName = new String(downLoadFileName.getBytes("UTF-8"), "ISO-8859-1");
        }
        response.setContentType("application/octet-stream");
        response.setHeader("content-type", "application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;fileName=" + downLoadFileName);// 设置文件名
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            outputStream.write(txtValue.getBytes());
        } finally {
            logger.info("下载人员基本信息.txt");
        }
        return null;
    }

    @RequestMapping("/upload/idCode")
    public R uploadIdCode(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        int count = 0;
        BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
        List<String> list = new ArrayList<>();
        String lineStr = null;
        while ((lineStr = reader.readLine()) != null) {
            logger.info("文本文件：{}", lineStr);
            list.add(lineStr);
        }
        reader.close();
        count = list.size();
        logger.info("文本文件OK");

        return R.ok().put("msg", "学员IC编码文件上传成功");
    }

    @RequestMapping("/openRfid")
    public R openRfid(@RequestParam Map<String, Object> params) throws Exception {
        String result = rfidModifyService.openRfid((String) params.get("com"));
        if (StringUtils.isNotBlank(result)) {
            return R.ok().put("msg", result);
        } else {
            return R.ok().put("msg", "成功打开读卡器");
        }
    }

    @RequestMapping("/closeRfid")
    public R closeRfid() throws Exception {

        String result = rfidModifyService.closeRfid();
        return R.ok().put("msg", result);
    }
}
